import xml.Pair;
import xmlpreprocessed.Node;
import xmlpreprocessed.Sentence;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: oye
 * Date: 04.11.11
 * Time: 11:49
 * To change this template use File | Settings | File Templates.
 */
public class RTEPhase1 {


    public String wordMatching(List<Pair> pairs, double threshold) throws IOException {
        File f = new File("wordMatching.txt");
    	FileWriter fileWriter = new FileWriter(f);
    	BufferedWriter writer = new BufferedWriter(fileWriter);

        writer.write("ranked: no"+"\n");

        for(Pair p : pairs){
            String[] wordsInH = p.getH().trim().split(" ");
            String[] wordsInT = p.getT().trim().split(" ");

            int commonWords = 0;
            for(String hWord : wordsInH){
                if(hWord.length()==0)
                    continue;
                if(hWord.charAt(hWord.length()-1) == ',' || hWord.charAt(hWord.length()-1) == '.')
                    hWord = hWord.substring(0, hWord.length()-1);
                for(String tWord : wordsInT){
                    if(tWord.length()==0)
                        continue;
                    if(tWord.charAt(tWord.length()-1) == ',' || tWord.charAt(tWord.length()-1) == '.')
                        tWord = tWord.substring(0, tWord.length()-1);
                    if(hWord.toLowerCase().equals(tWord.toLowerCase())){
                        commonWords++;
                        break;
                    }
                }
            }

            double wordMatch = (double)commonWords/(double)wordsInH.length;

            if(wordMatch>=threshold){
                writer.write(p.getId() + " YES\n");
            }else{
                writer.write(p.getId() + " NO\n");
            }
        }
        writer.close();
        return "wordMatching.txt";
    }

    public String lemmaMatching(List<xmlpreprocessed.Pair> pairs, double threshold) throws IOException{
        File f = new File("lemmaMatching.txt");
        FileWriter fileWriter = new FileWriter(f);
        BufferedWriter writer = new BufferedWriter(fileWriter);

        writer.write("ranked: no"+"\n");

        for(xmlpreprocessed.Pair p : pairs){
            List<Sentence> sentencesInT = p.getText().getProperties();
            
            List<Node> wordsInT = new ArrayList<Node>();
            for(Sentence sentence : sentencesInT){
                wordsInT.addAll(sentence.getProperties());
            }

            List<Sentence> sentencesInH = p.getHypothesis().getProperties();

            List<Node> wordsInH = new ArrayList<Node>();
            for(Sentence sentence : sentencesInH){
                wordsInH.addAll(sentence.getProperties());
            }

            int commonLemmas = 0;
            for (Node hNode : wordsInH) {
                if(hNode != null){
                    if(hNode.getWord() == null || hNode.getLemma() == null)
                        continue;
                    else if(hNode.getWord().equals(".") || hNode.getWord().equals(","))
                        continue;
                }

                for (Node tNode : wordsInT) {
                    if(tNode != null){
                        if(tNode.getWord() == null || tNode.getLemma() == null)
                            continue;
                        else if(tNode.getWord().equals(".") || tNode.getWord().equals(","))
                            continue;
                    }

                    if(hNode.getLemma().equals(tNode.getLemma())){
                        commonLemmas++;
                        break;
                    }
                }
            }

            double wordMatch = (double)commonLemmas/(double)wordsInH.size();

            if(wordMatch>=threshold){
                writer.write(p.getId() + " YES\n");
            }else{
                writer.write(p.getId() + " NO\n");
            }
        }
        writer.close();
        return "lemmaMatching.txt";
    }

    public String lemmaPOSMatching(List<xmlpreprocessed.Pair> pairs, double threshold) throws IOException{
        File f = new File("lemmaPOSMatching.txt");
        FileWriter fileWriter = new FileWriter(f);
        BufferedWriter writer = new BufferedWriter(fileWriter);

        writer.write("ranked: no"+"\n");

        for(xmlpreprocessed.Pair p : pairs){
            List<Sentence> sentencesInT = p.getText().getProperties();

            List<Node> wordsInT = new ArrayList<Node>();
            for(Sentence sentence : sentencesInT){
                wordsInT.addAll(sentence.getProperties());
            }

            List<Sentence> sentencesInH = p.getHypothesis().getProperties();

            List<Node> wordsInH = new ArrayList<Node>();
            for(Sentence sentence : sentencesInH){
                wordsInH.addAll(sentence.getProperties());
            }

            int commonLemmas = 0;
            for (Node hNode : wordsInH) {
                if(hNode != null){
                    if(hNode.getWord() == null || hNode.getLemma() == null)
                        continue;
                    else if(hNode.getWord().equals(".") || hNode.getWord().equals(","))
                        continue;
                }

                for (Node tNode : wordsInT) {
                    if(tNode != null){
                        if(tNode.getWord() == null || tNode.getLemma() == null)
                            continue;
                        else if(tNode.getWord().equals(".") || tNode.getWord().equals(","))
                            continue;
                    }

                    if(hNode.getWord().equals(tNode.getWord()) && !hNode.getPosTag().equals(tNode.getPosTag())){
                        continue;
                    }

                    if(hNode.getLemma().equals(tNode.getLemma())){
                        commonLemmas++;
                        break;
                    }
                }
            }

            double wordMatch = (double)commonLemmas/(double)wordsInH.size();

            if(wordMatch>=threshold){
                writer.write(p.getId() + " YES\n");
            }else{
                writer.write(p.getId() + " NO\n");
            }
        }
        writer.close();
        return "lemmaPOSMatching.txt";
    }


    public String bleuMatching(List<Pair> pairs, double threshold) throws IOException{
        File f = new File("bleuMatching.txt");
        FileWriter fileWriter = new FileWriter(f);
        BufferedWriter writer = new BufferedWriter(fileWriter);

        writer.write("ranked: no"+"\n");

        for (Pair p : pairs) {
            String[] wordsInH = p.getH().trim().split(" ");
            String[] wordsInT = p.getT().trim().split(" ");

            List<String> cleanH = new ArrayList<String>();
            List<String> cleanT = new ArrayList<String>();
            for(String hWord : wordsInH){
                if(hWord.length()==0)
                    continue;
                if(hWord.charAt(hWord.length()-1) == ',' || hWord.charAt(hWord.length()-1) == '.')
                    hWord = hWord.substring(0, hWord.length()-1);
                cleanH.add(hWord.toLowerCase());
            }
            for(String tWord : wordsInT){
                if(tWord.length()==0)
                    continue;
                if(tWord.charAt(tWord.length()-1) == ',' || tWord.charAt(tWord.length()-1) == '.')
                    tWord = tWord.substring(0, tWord.length()-1);
                cleanT.add(tWord.toLowerCase());
            }

            double temp = calcNGrams(cleanH, cleanT);
            double modBleu = (1.0/4.0)*temp;
            if(modBleu>=threshold){
                writer.write(p.getId() + " YES\n");
            }else{
                writer.write(p.getId() + " NO\n");
            }
        }

        writer.close();
        return "bleuMatching.txt";
    }

    private double calcNGrams(List<String> h, List<String> t){
        double sum = 0;
        for(int n=1; n<5; n++){
            double nSum=0;
            double numGrams=0;
            for(int i=0; (i+n)<=h.size(); i++){
                List<String> hGram = h.subList(i, i+n);
                for(int j=0; (j+n)<=t.size(); j++){
                    List<String> tGram = t.subList(j, j+n);
                    if(checkNGramEquality(hGram, tGram)) {
                        nSum++;
                        break;
                    }
                }

                numGrams++;
            }
            sum += nSum/numGrams;
        }
        return sum;
    }

    private boolean checkNGramEquality(List<String> gram1, List<String> gram2){
        for (String g1 : gram1) {
            if(!g1.equals(gram2.get(gram1.indexOf(g1))))
                return false;
        }
        return true;
    }

    public String idfMatching(List<Pair> pairs, double threshold) throws IOException{
        BufferedWriter writer = new BufferedWriter(new FileWriter(new File("idfMatching.txt")));

        writer.write("ranked: no\n");

        HashMap<String, Double> idfMap = calcIDFs(pairs);

        for (Pair pair : pairs) {
            String[] wordsInH = pair.getH().trim().split(" ");
            String[] wordsInT = pair.getT().trim().split(" ");

            double totHypIdfSum=0;
            double tempSum=0;
            for (String hWord : wordsInH) {
                if(hWord.length()==0)
                    continue;
                if(hWord.charAt(hWord.length()-1) == ',' || hWord.charAt(hWord.length()-1) == '.')
                    hWord = hWord.substring(0, hWord.length()-1);
                hWord = hWord.trim().toLowerCase();
                for (String tWord : wordsInT) {
                    if(tWord.length()==0)
                        continue;
                    if(tWord.charAt(tWord.length()-1) == ',' || tWord.charAt(tWord.length()-1) == '.')
                        tWord = tWord.substring(0, tWord.length()-1);
                    tWord = tWord.trim().toLowerCase();
                    if(hWord.equals(tWord))
                        tempSum += idfMap.get(hWord);

                }
                totHypIdfSum += tempSum;
            }

            double idfWordMatch = tempSum/totHypIdfSum;
            if(idfWordMatch>=threshold){
                writer.write(pair.getId() + " YES\n");
            }else{
                writer.write(pair.getId() + " NO\n");
            }
        }
        writer.close();
        return "idfMatching.txt";
    }

    private HashMap<String, Double> calcIDFs(List<Pair> pairs){
        HashMap<String, Double> wordOccurences = new HashMap<String, Double>();

        for (Pair pair : pairs) {
            String[] wordsInH = pair.getH().trim().split(" ");
            String[] wordsInT = pair.getT().trim().split(" ");

            boolean foundBefore = false;
            for(String hWord : wordsInH){
                if(hWord.length()==0)
                    continue;
                if(hWord.charAt(hWord.length()-1) == ',' || hWord.charAt(hWord.length()-1) == '.')
                    hWord = hWord.substring(0, hWord.length()-1);
                hWord = hWord.trim().toLowerCase();
                if(!wordOccurences.containsKey(hWord)){
                    wordOccurences.put(hWord, 1.0);
                }else{
                    if(!foundBefore){
                        wordOccurences.put(hWord, wordOccurences.get(hWord)+1.0);
                        foundBefore = true;
                    }
                }
            }
            foundBefore = false;
            for(String tWord : wordsInT){
                if(tWord.length()==0)
                    continue;
                if(tWord.charAt(tWord.length()-1) == ',' || tWord.charAt(tWord.length()-1) == '.')
                    tWord = tWord.substring(0, tWord.length()-1);
                tWord = tWord.trim().toLowerCase();
                if(!wordOccurences.containsKey(tWord)){
                    wordOccurences.put(tWord, 1.0);
                }else{
                    if(!foundBefore){
                        wordOccurences.put(tWord, wordOccurences.get(tWord)+1.0);
                        foundBefore = true;
                    }
                }
            }
        }
        for (String word : wordOccurences.keySet()) {
            wordOccurences.put(word, 1.0/wordOccurences.get(word));
        }
        return wordOccurences;
    }
}
